\bibliographystyle{gbt7714-2005}

\chapter{MVC模式}
\label{mvc}

\epigraphhead[60]{\epigraph{开始，上帝就给每个民族一只陶杯，从这杯中，人们饮入了他们的生活。}{\textit{迪格尔印第安人箴言}}}

我们投入时间和精力来开发程序，主要目标是构建实现既定目标的系统。但是，在大多数场合下，这还远远不够，我们还要使代码易于协作开发。\cite{赞特斯彻，2011}

我们想要干净和聪明的代码，也想要一份经过良好设计的代码库，分享、阅读和部署项目的机制和代码一样重要。

在20世纪70年代，设计模式（Design Pattern）作为一种描述和解决问题的方案提一次被提出。实际上这种想法源自建筑学，而不是计算机科学。在20世纪90年代初，面向对象编程使用了相同的技术来命名和描述软件问题。这方面的经典著作是《设计模式——可复用面向对象软件的基础》。\cite{Gamma，2000}

\section{模式}
作为程序员，我们遇到的大部分问题其实都已被其他程序员一再地处理了。模式便是特定环境下同类问题的一种解决方案。\cite{Gamma，2000}

我们在进行Web开发时，会遇到如何处理一个请求？如何将请求数据转换成系统对应的指令？如何获得数据？如何显示结果之类的问题，随着经验的积累，我们或许优雅或许困难地回答了这些问题，并总结出一些非正式的、可在项目中重复使用的解决方案，而这些方案便是模式。

每个模式都描述着一种在我们的环境中一遍又一遍地出现的问题，并描述了对该问题的核心解决方案。以此方式你可以使用该方案多次，而从不需要重复做同样的事情。\cite{Alexander，1977}

\section{MVC模式}
MVC模式（Model-View-Controller）是软件工程中的一种软件架构模式，把软件系统分为三个基本部分：模型（Model）、视图（View）和控制器（Controller）。三者联系见图\ref{fig:mvc}。

MVC模式最早由Trygve Reenskaug在1978年提出，是施乐帕罗奥多研究中心（Xerox PARC）在20世纪80年代为程序语言Smalltalk发明的一种软件设计模式。MVC模式的目的是实现一种动态的程序设计，使后续对程序的修改和扩展简化，并且使程序某一部分的重复利用成为可能。除此之外，此模式通过对复杂度的简化，使程序结构更加直观。软件系统通过对自身基本部分分离的同时也赋予了各个基本部分应有的功能。
\begin{description}
\item [控制器] 负责转发请求，对请求进行处理。
\item [视图] 界面设计人员进行图形界面设计。
\item [模型] 程序员编写程序应有的功能（实现算法等等）、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。
\end{description}

\begin{figure}
	\centering
	\includegraphics[width=120mm]{raw/mvc.pdf}
	\caption{MVC模型}
	\label{fig:mvc}
\end{figure}

其实，这种对工作抽样的分工模式，不仅适用于开发软件，也适用于其他广泛的设计和组织工作。

\section{对MVC模式的批评}
尽管MVC架构模式已被广泛采用，但是，有人认为随着B/S和互联网应用不断普及，Web 2.0和社会化媒体 以及游戏等大量频繁交互应用普及，相对静止的MVC模式已经不适合高度交互注重行为的应用了。\cite{jdon.com，2014}

相反，《对象设计：角色、责任和协作》(Object Design: Roles, Responsibilities, and Collaborations)一书提出职责驱动开发，将对象行为上升为重点，提出了对象其实是在扮演某种角色，而角色是有职责的，然后会在一定场景上下文环境中实施一定交互行为。该书总结了集中式控制器4大缺点，MVC的控制器实际就属于这种集中式控制器风格：\cite{Brock，2006}

1.Control logic can get overly complex. 控制器会变得复杂，有的action都几乎上千行了.

2.Controllers can become dependent on information holders' contents.控制器变得依赖信息数据中心或数据库了，控制器做很多事情，意味着领域对象就做很少事情，控制器最后不是只会做什么，决定战略性的事情，也和怎么做，如何实现等战术问题耦合。

3.Objects can become coupled indirectly through the actions of their controller. 对象将间接地通过控制器的action耦合在一起，一个对象在控制器中查询获得，然后复制给另外一个对象，这两个对象就耦合在一起。

4.The only interesting work is done in the controller.唯一有趣的工作是做控制器，Responsibilities职责被吸进控制器对象，只将一些行为留给角色模型完成，重要的事情都集中在控制器中了。

MVC的控制器是Mediator模式一种，也属于一种集中式控制器，它与观察者模式重大区别是：Mediator模式封装了通讯，而Observer分散通讯，从通讯角度来看，控制器也有其固有的缺陷，容易变成大而全高度耦合的集中器，这些都是为OO所不容。

\section{用PHP简单实现MVC模式}

\subsection{设计思路}
为了体现MVC模式将内容和表现相分离的思想，我们创建了controllers目录存放控制器，用models目录存放模型，而用views目录存放视图文件，主入口文件为index.php。

\subsection{入口}
\lstinputlisting{example/PHP/10-mvc/index.php}

\subsection{控制器}
\lstinputlisting{example/PHP/10-mvc/controllers/UserController.php}
在上面的例子中，我们可以通过如下地址访问User控制器的hello方法：
\begin{lstlisting}
http://localhost/PHP/10-mvc/index.php?c=User&m=index
\end{lstlisting}

\subsection{视图}
\lstinputlisting{example/PHP/10-mvc/views/User/index.php}

在视图中，我们将PHP变量嵌入到HTML文件中，从而实现了内容和表现之间的分离。

\subsection{模型}
\lstinputlisting{example/PHP/10-mvc/models/User/UserModel.php}

\bibliography{../bib/yangjh}
